﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AMS.DD35.Common;
using AMS.DD35.WebMVP.Models;
using AMS.DD35.WebMVP.Presenters;
using AMS.DD35.Common.Data;
using AMS.Core;
using AMS.DD35.WcfConnector;
using AMS.DD35.WebMVP.State;

namespace AMS.DD35.WebMVP.Views
{
    public partial class CharacterView : System.Web.UI.Page, ICharacterView
    {
        CharacterPresenter _presenter;
        IStaticLookupService _lookup;

        #region Properties

        public string UserName
        {
            get { return hidUserName.Value; }
            set { hidUserName.Value = value; }
        }

        public long CharacterID
        {
            get { return Int64.Parse(hidCharacterID.Value); }
            set { hidCharacterID.Value = value.ToString(); }
        }

        public string CharacterName
        {
            get { return txtCharacterName.Text; }
            set { txtCharacterName.Text = value; }
        }

        // base stats

        public byte BaseStrength
        {
            get { return byte.Parse(txtBaseStr.Text); }
            set { txtBaseStr.Text = value.ToString(); }
        }

        public byte BaseDexterity
        {
            get { return byte.Parse(txtBaseDex.Text); }
            set { txtBaseDex.Text = value.ToString(); }
        }

        public byte BaseConstitution
        {
            get { return byte.Parse(txtBaseCon.Text); }
            set { txtBaseCon.Text = value.ToString(); }
        }

        public byte BaseIntelligence
        {
            get { return byte.Parse(txtBaseInt.Text); }
            set { txtBaseInt.Text = value.ToString(); }
        }

        public byte BaseWisdom
        {
            get { return byte.Parse(txtBaseWis.Text); }
            set { txtBaseWis.Text = value.ToString(); }
        }

        public byte BaseCharisma
        {
            get { return byte.Parse(txtBaseCha.Text); }
            set { txtBaseCha.Text = value.ToString(); }
        }

        public MoralAlignment MoralAlignment
        {
            get
            {
                return EnumHelper.ParseEnum<MoralAlignment>(ddlMoralAlignment.SelectedValue);
            }
            set
            {
                for (int i = 0; i < ddlMoralAlignment.Items.Count; i++)
                {
                    if (ddlMoralAlignment.Items[i].Value == value.ToString())
                    {
                        ddlMoralAlignment.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

        public EthicalAlignment EthicalAlignment
        {
            get
            {
                return EnumHelper.ParseEnum<EthicalAlignment>(ddlEthicalAlignment.SelectedValue);
            }
            set
            {
                for (int i = 0; i < ddlEthicalAlignment.Items.Count; i++)
                {
                    if (ddlEthicalAlignment.Items[i].Value == value.ToString())
                    {
                        ddlEthicalAlignment.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

        public short RaceID
        {
            get { return short.Parse(ddlRace.SelectedValue); }
            set
            {
                for (int i = 0; i < ddlDeity.Items.Count; i++)
                {
                    if (ddlRace.Items[i].Value == value.ToString())
                    {
                        ddlRace.SelectedIndex = i;
                        break;
                    }
                }
            }
        }
        //string Enthnicity { get; set; }

        public short DeityID
        {
            get { return short.Parse(ddlDeity.SelectedValue); }
            set
            {
                for (int i = 0; i < ddlDeity.Items.Count; i++)
                {
                    if (ddlDeity.Items[i].Value == value.ToString())
                    {
                        ddlDeity.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

        public string Sex
        {
            get { return ddlSex.SelectedValue; }
            set
            {
                if (value.ToLower() == "male")
                    ddlSex.SelectedIndex = 0;
                else
                    ddlSex.SelectedIndex = 1;
            }
        }

        public byte Height
        {
            get { return byte.Parse(txtHeight.Text); }
            set { txtHeight.Text = value.ToString(); }
        }

        public string HeightUnits
        {
            get { return lblHeightUnits.Text; }
            set { lblHeightUnits.Text = value; }
        }

        public byte Weight
        {
            get { return byte.Parse(txtWeight.Text); }
            set { txtWeight.Text = value.ToString(); }
        }

        public string WeightUnits
        {
            get { return lblWeightUnits.Text; }
            set { lblWeightUnits.Text = value; }
        }
        
        public string HairColor
        {
            get { return txtHairColor.Text; }
            set { txtHairColor.Text = value; }
        }

        public string EyeColor
        {
            get { return txtEyeColor.Text; }
            set { txtEyeColor.Text = value; }
        }

        // inherent gains
        
        public Dictionary<int, Ability> InherentAbilityGains { get; set; }

        // List<CharacterLevel>

        public IEnumerable<string> Classes { get; set; }

        // skill points distribution
        
        public Dictionary<Skill, int[][]> SkillPoints { get; set; } // skill, level, points

        // feats
        
        public IEnumerable<string> Feats { get; set; }

        public int Experience
        {
            get
            {
                if (String.IsNullOrEmpty(txtExperience.Text))
                    return 0;

                return int.Parse(txtExperience.Text);
            }
            set { txtExperience.Text = value.ToString(); }
        }

        // coinage

        public int Copper
        {
            get
            {
                if (String.IsNullOrEmpty(txtCopper.Text))
                    return 0; 
                
                return Int32.Parse(txtCopper.Text);
            }
            set { txtCopper.Text = value.ToString(); }
        }

        public int Silver
        {
            get
            {
                if (String.IsNullOrEmpty(txtSilver.Text))
                    return 0;

                return Int32.Parse(txtSilver.Text);
            }
            set { txtSilver.Text = value.ToString(); }
        }

        public int Gold
        {
            get
            {
                if (String.IsNullOrEmpty(txtGold.Text))
                    return 0;

                return Int32.Parse(txtGold.Text);
            }
            set { txtGold.Text = value.ToString(); }
        }

        public int Platinum
        {
            get
            {
                if (String.IsNullOrEmpty(txtPlatinum.Text))
                    return 0;

                return Int32.Parse(txtPlatinum.Text);
            }
            set { txtPlatinum.Text = value.ToString(); }
        }

        public string StatusMessage
        {
            get { return lblSaveMessage.Text; }
            set { lblSaveMessage.Text = value; }
        }
        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            ICharacterService character = new CharacterProxy();
            AMS.DD35.WebMVP.State.IStateManager state = new StateManager();
            ICharacterModel model = new CharacterModel(character, state);
            _presenter = new CharacterPresenter(this, model, state);
            _lookup = new StaticLookupProxy();

            // hook up events
            model.SaveSucceeded += new EventHandler(HandleSaveSucceeded);
            model.SaveFailed += new EventHandler(HandleSaveFailed);

            if (Page.IsPostBack)
                return;

            LoadOptions();
            LoadCharacter();
        }

        private void LoadOptions()
        {
            LoadRaces();
            LoadDeities();
            LoadSexes();
            LoadEthicalAlignments();
            LoadMoralAlignments();
        }

        private void LoadRaces()
        {
            Dictionary<int, string> races = _lookup.GetRaces();
            ddlRace.DataSource = races;
            ddlRace.DataTextField = "Value";
            ddlRace.DataValueField = "Key";
            ddlRace.DataBind();
        }

        private void LoadDeities()
        {
            Dictionary<int, string> deities = _lookup.GetDeities();
            ddlDeity.DataSource = deities;
            ddlDeity.DataTextField = "Value";
            ddlDeity.DataValueField = "Key";
            ddlDeity.DataBind();
        }

        private void LoadSexes()
        {
            ddlSex.Items.Add("Male");
            ddlSex.Items.Add("Female");
        }

        private void LoadEthicalAlignments()
        {
            foreach (EthicalAlignment ea in Enum.GetValues(typeof(EthicalAlignment)))
                ddlEthicalAlignment.Items.Add(ea.ToString());
        }

        private void LoadMoralAlignments()
        {
            foreach (MoralAlignment ma in Enum.GetValues(typeof(MoralAlignment)))
                ddlMoralAlignment.Items.Add(ma.ToString());
        }

        private void LoadCharacter()
        {
            _presenter.LoadCharacter();
        }

        public CharacterData GetCharacterData()
        {
            // parse out all fields
            // base fields
            CharacterData characterData = new CharacterData();
            characterData.CharacterID = this.CharacterID;
            characterData.UserName = this.UserName;
            characterData.CharacterName = this.CharacterName;
            characterData.BaseStrength = this.BaseStrength;
            characterData.BaseDexterity = this.BaseDexterity;
            characterData.BaseConstitution = this.BaseConstitution;
            characterData.BaseIntelligence = this.BaseIntelligence;
            characterData.BaseWisdom = this.BaseWisdom;
            characterData.BaseCharisma = this.BaseCharisma;
            characterData.RaceID = this.RaceID;
            characterData.Experience = this.Experience;
            characterData.Sex = this.Sex;
            characterData.Height = this.Height;
            characterData.HeightUnits = this.HeightUnits;
            characterData.Weight = this.Weight;
            characterData.WeightUnits = this.WeightUnits;
            characterData.HairColor = this.HairColor;
            characterData.EyeColor = this.EyeColor;
            characterData.MoralAlignment = this.MoralAlignment;
            characterData.EthicalAlignment = this.EthicalAlignment;
            characterData.DeityID = this.DeityID;

            // coinage

            // feats

            // skills

            // classes

            return characterData;
        }

        public void LoadCharacterData(CharacterData characterData)
        {
            this.CharacterID = characterData.CharacterID;
            this.UserName = characterData.UserName;
            this.CharacterName = characterData.CharacterName;
            this.BaseStrength = characterData.BaseStrength;
            this.BaseDexterity = characterData.BaseDexterity;
            this.BaseConstitution = characterData.BaseConstitution;
            this.BaseIntelligence = characterData.BaseIntelligence;
            this.BaseWisdom = characterData.BaseWisdom;
            this.BaseCharisma = characterData.BaseCharisma;
            this.RaceID = characterData.RaceID;
            this.Experience = characterData.Experience;
            this.Sex = characterData.Sex;
            this.Height = characterData.Height;
            this.HeightUnits = characterData.HeightUnits;
            this.Weight = characterData.Weight;
            this.WeightUnits = characterData.WeightUnits;
            this.HairColor = characterData.HairColor;
            this.EyeColor = characterData.EyeColor;
            this.MoralAlignment = characterData.MoralAlignment;
            this.EthicalAlignment = characterData.EthicalAlignment;
            this.DeityID = characterData.DeityID;

            // coinage

            // feats

            // skills

            // classes
        }

        // TODO: add levels?

        protected void HandleBtnSave_Click(object sender, EventArgs args)
        {
            _presenter.Save();
        }

        protected void HandleBtnQuit_Click(object sender, EventArgs args)
        {
            Response.Redirect("CharactersView.aspx", false);
        }

        private void HandleSaveSucceeded(object sender, EventArgs args)
        {
            _presenter.SaveSucceeded();
        }

        private void HandleSaveFailed(object sender, EventArgs args)
        {
            _presenter.SaveFailed();
        }
    }
}